import React from "react";

import NavHeader from "../../components/NavHeader";

import "./index.scss";
import "./index.module.css";
import { API } from "../../utils/api";

// 导入List组件
import { List, AutoSizer } from "react-virtualized";
// 导入 utils 获取当前定位城市的方法
import { getCurrentCity } from "../../utils/index";

// 接口返回数据格式
//  [{ label: '北京', value: 'AREA|88cff55c-aaa4-e2e0', pinyin: 'beijing',...},...]
const formatCityData = (list) => {
  const cityList = {};
  // const cityIndex = []

  // 1 遍历list数组
  list.forEach((item) => {
    // 2 获取每一个城市的首字母
    const first = item.short.substr(0, 1);
    // 3 判断 cityList 中是否有该分类
    if (cityList[first]) {
      // 4 如果有，直接往该分类中push数据
      // cityList[first] => [{}, {}]
      cityList[first].push(item);
    } else {
      // 5 如果没有，就先创建一个数组，然后，把当前城市信息添加到数组中
      cityList[first] = [item];
    }
  });

  // 获取索引数据
  const cityIndex = Object.keys(cityList).sort();

  return {
    cityList,
    cityIndex,
  };
};

// 索引(A、B等)的高度
const TITLE_HEIGHT = 36;
// 每个城市名称的高度
const NAME_HEIGHT = 50;

// 有房源的城市
const HOUSE_CITY = ["北京", "上海", "广州", "深圳"];

// 封装处理字母索引的方法
const formatCityIndex = (letter) => {
  switch (letter) {
    case "#":
      return "当前定位";
    case "hot":
      return "热门城市";
    default:
      return letter.toUpperCase();
  }
};
export default class CityList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      cityList: {},
      cityIndex: [],
      // 指定右侧列表高亮的索引
      activeIndex: 0,
    };
    // 创建ref对象
    this.cityListComponent = React.createRef();
  }

  async componentDidMount() {
    await this.getCityList();
    // 对于点击索引无法正确定位的问题,调用 List 组件的 measureAllRows 方法,提前计算高度来解决。
    // 注意：调用这个方法的时候，需要保证 List 组件中已经有数据了！
    this.cityListComponent.current.measureAllRows();
  }
  // 获取城市数据列表
  async getCityList() {
    const res = await API.get("/area/city?level=1");
    const { cityList, cityIndex } = formatCityData(res.data.body);

    // 获取热门城市
    const hotRes = await API.get("/area/hot");
    // 将数据添加到 cityList
    cityList["hot"] = hotRes.data.body;
    // 将数据添加到 cityIndex 索引为一的位置 unshift
    cityIndex.unshift("hot");

    // 获取当前定位城市
    const curCity = await getCurrentCity();
    cityList["#"] = [curCity];
    cityIndex.unshift("#");
    this.setState({
      cityList,
      cityIndex,
    });
  }
  // List组件渲染每一行的方法：
  rowRenderer = ({
    key, // Unique key within array of rows
    index, // 索引号
    isScrolling, // 当前项是否正在滚动中
    isVisible, // 当前项在 List 中是可见的
    style, // 注意：重点属性，一定要给每一个行数据添加该样式！作用：指定每一行的位置
  }) => {
    // 获取每一行的字母索引
    const { cityIndex, cityList } = this.state;
    const letter = cityIndex[index];

    // 获取指定字母索引下的城市列表数据

    return (
      <div key={key} style={style} className="city">
        <div className="title">{formatCityIndex(letter)}</div>
        {cityList[letter].map((item) => (
          <div
            className="name"
            key={item.value}
            onClick={() => this.changeCity(item)}
          >
            {item.label}
          </div>
        ))}
      </div>
    );
  };
  changeCity = ({ value, label }) => {
    // const index = HOUSE_CITY.findIndex((item) => item === label);
    if (HOUSE_CITY.indexOf(label) > -1) {
      // 有房源信息
      localStorage.setItem("hkzf_city", JSON.stringify({ label, value }));
      this.props.history.go(-1);
    }
  };
  //  创建动态计算每一行高度的方法
  getRowHeight = ({ index }) => {
    // 索引标题高度 + 每行城市数量 * 城市名称的高度
    const { cityList, cityIndex } = this.state;
    const height =
      TITLE_HEIGHT + NAME_HEIGHT * cityList[cityIndex[index]].length;
    return height;
  };
  /**
   * 1 给索引列表项绑定点击事件
   * 2 在点击事件中,通过index 获取到当前项索引
   * 3 调用List 组件的 scrollToRow 方法,让 List 组件滚动到指定行
   *
   * 3.1 在 constructor 中,调用 React.createRef() 创建 ref 对象
   * 3.2 将创建好的 ref 对象,添加为 List 组件的 ref属性
   * 3.3 通过ref 的current 属性,获取到组件实例,再调用组件的 scrollToRow 方法
   *
   * 4 设置 List 组件的 scrollToAlignment 配置项值为start,保证被点击行出现在页面顶部
   * 5 对于点击索引无法正确定位的问题,调用 List 组件的 measureAllRows 方法,提前计算高度来解决。
   *
   */

  // 渲染右侧索引列表的方法
  renderCityIndex = () => {
    const { cityIndex, activeIndex } = this.state;
    return cityIndex.map((item, index) => (
      <li
        className="city-index-item"
        key={item}
        onClick={() => this.cityListComponent.current.scrollToRow(index)}
      >
        <span className={activeIndex === index ? "index-active" : ""}>
          {item === "hot" ? "热" : item.toUpperCase()}
        </span>
      </li>
    ));
  };
  // 用于获取List组件中渲染行的信息
  onRowsRendered = ({ startIndex }) => {
    if (startIndex !== this.state.activeIndex) {
      this.setState({
        activeIndex: startIndex,
      });
    }
  };

  render() {
    return (
      <div className="cityList">
        <NavHeader>城市选择</NavHeader>
        {/* 城市列表 */}
        <AutoSizer>
          {({ width, height }) => (
            <List
              ref={this.cityListComponent}
              height={height}
              width={width}
              rowCount={this.state.cityIndex.length}
              rowHeight={this.getRowHeight}
              rowRenderer={this.rowRenderer}
              onRowsRendered={this.onRowsRendered}
              scrollToAlignment="start"
            />
          )}
        </AutoSizer>
        <ul className="city-index">{this.renderCityIndex()}</ul>
      </div>
    );
  }
}
